﻿#pragma once
#include <QtWidgets/qapplication.h>
#include <qdatetime.h>
#include <qwidget.h>
#include "QtWidgetsClass.h"
#include <Windows.h>
#include "algorithmplugin.h"
#include "cameraplugin.h"
#include "files/syslog.h"
#include <iostream>
#include <qfile.h>
#include <qtextstream.h>
#include <sstream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <chrono>
#include <qdir.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <qdebug.h>

#include "math.h"

#include "../AmPackAlgPlugin/AmPackAlgPlugin.h"

QVector<ImageData_t> vecImg;
std::chrono::system_clock::time_point start_time_point;

using namespace std::literals;

Q_DECLARE_METATYPE(cv::Mat)

#include <QFile>
#include <QTextStream>

//void writeTextFile(const QString& fileName, const QString& text) {
//	QFile file(fileName);
//	if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
//		// 处理错误，例如可以抛出异常或者返回错误标志
//		return;
//	}
//
//	QTextStream out(&file);
//	out << text;
//	file.close();
//}

//#pragma comment(lib,"AmPackAlgPlugin.lib")
struct MyStruct
{
	float x;
	float y;
	float z;
	float g;
};

bool GetValueFromString(std::string string_header, std::string key, float& value)
{
	size_t pos = string_header.find(key);
	if (pos == std::string::npos)
	{
		value = 1;
	}
	else
	{
		size_t pos1 = string_header.find("\n", pos);
		if (pos1 == std::string::npos)
		{
			return false;
		}
		std::string back_str = string_header.substr(pos + key.size(), pos1 - pos - key.size());
		value = atof(back_str.c_str());
	}

	return true;
}
//pcp
bool ReadCloud3D(const char* filename, cv::Mat& cloud, cv::Mat& xyz, cv::Mat& gray)
{
	auto startTime = std::chrono::system_clock::now();
	//Step-5:读写文件头数据
	std::ifstream cloud_file(filename);
	//定义点云的分辨率
	float cloud_dx;
	float cloud_dy;
	float cloud_format;
	float cloud_minx;
	float cloud_miny;
	float cloud_minz;
	float cloud_maxx;
	float cloud_maxy;
	float cloud_maxz;
	//定义点云的size,width,height.
	float cloud_size;
	float cloud_width;
	float cloud_height;
	float interval_valid;
	float  channel = 0;
	int point_type_value = -1;
	float expose = 0;
	std::string  timestamp;
	std::string  device_message;
	//记录文件读取行数
	int index = 1;
	std::string string_header;
	bool isFindData = false;
	while (!cloud_file.eof())
	{
		//读取每一行的内容
		std::string  string_line;
		std::getline(cloud_file, string_line);
		std::size_t posdata = string_line.find("data");
		if (!isFindData)
		{
			if (posdata != std::string::npos)
			{
				isFindData = true;
				break;
			}
		}
		string_header = string_header + string_line + "\n";
		index++;
	}
	if (!isFindData)
	{
		return false;
	}
	std::string type = "type:";
	std::size_t pos = string_header.find(type);
	if (pos == std::string::npos)
	{
		return false;
	}
	std::size_t pos1 = string_header.find("\n", pos);
	if (pos1 == std::string::npos)
	{
		return false;
	}

	std::string back_str = string_header.substr(pos + type.size(), pos1 - pos - type.size());
	if (back_str == "POINTXYZ")
	{
		channel = 3;
		point_type_value = 0;
	}
	else if (back_str == "POINTXYZNORMAL")
	{
		channel = 6;
		point_type_value = 1;
	}
	else if (back_str == "POINTXYZGRAY")
	{
		channel = 4;
		point_type_value = 2;
	}
	else if (back_str == "POINTXYZDIVERSE")
	{
		channel = 4;
		point_type_value = 3;
	}
	if (point_type_value < 0)
	{
		return false;
	}
	GetValueFromString(string_header, "size:", cloud_size);
	GetValueFromString(string_header, "width:", cloud_width);
	GetValueFromString(string_header, "height:", cloud_height);
	GetValueFromString(string_header, "interval_valid:", interval_valid);
	GetValueFromString(string_header, "minx:", cloud_minx);
	GetValueFromString(string_header, "miny:", cloud_miny);
	GetValueFromString(string_header, "minz:", cloud_minz);
	GetValueFromString(string_header, "maxx:", cloud_maxx);
	GetValueFromString(string_header, "maxy:", cloud_maxy);
	GetValueFromString(string_header, "maxz:", cloud_maxz);
	GetValueFromString(string_header, "dx:", cloud_dx);
	GetValueFromString(string_header, "dy:", cloud_dy);
	GetValueFromString(string_header, "expose:", expose);

	auto startTime2 = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - startTime).count();
	std::cout << duration << "\n";
	auto startTime3 = std::chrono::system_clock::now();
#ifdef _WINDOWS
	FILE* file = nullptr;
	fopen_s(&file, filename, "r");
#else
	FILE* file = fopen(filename, "r");
#endif
	if (!file)
	{
		return false;
	}
	for (int i = 0; i < index; i++)
		fscanf(file, "%*[^\n]%*c");
	//Step-2:开始正式读取文本内容 

	cloud = cv::Mat(cloud_height, cloud_width, CV_32FC1);
	gray = cv::Mat(cloud_height, cloud_width, CV_8UC1);
	xyz = cv::Mat(4, cloud_size, CV_32FC1);
	float col_1, col_2, col_3, col_4, col_5, col_6;
	{
		switch (point_type_value)
		{
		case 0:
		{

			for (size_t h = 0; h < cloud_size; h++)
			{
#ifdef _WINDOWS
				if (fscanf_s(file, "%f %f %f\n", &col_1, &col_2, &col_3) != 3)
#else
				if (fscanf(file, "%f %f %f\n", &col_1, &col_2, &col_3) != 3)
#endif
				{
					fclose(file);
					return false;
				}
				//int index = h * channel;
				//cloud->data[index] = col_1;
				//cloud->data[index + 1] = col_2;
				//cloud->data[index + 2] = col_3;

				cloud.at<float>(h, 0) = col_1;
				cloud.at<float>(h, 1) = col_2;
				cloud.at<float>(h, 2) = col_3;
				cloud.at<float>(h, 3) = 1;
			}
		}
		break;
		case 1:
		{
			for (int h = 0; h < int(cloud_size); h++)
			{
#ifdef _WINDOWS	
				if (fscanf_s(file, "%f %f %f %f\n", &col_1, &col_2, &col_3, &col_4) != 4)
#else
				if (fscanf(file, "%f %f %f %f\n", &col_1, &col_2, &col_3, &col_4) != 4)
#endif
				{
					fclose(file);
					return false;
				}
				//int index = h * channel;
				//cloud->data[index] = col_1;
				//cloud->data[index + 1] = col_2;
				//cloud->data[index + 2] = col_3;
				//cloud->data[index + 3] = col_4;

				cloud.at<float>(h, 0) = col_1;
				cloud.at<float>(h, 1) = col_2;
				cloud.at<float>(h, 2) = col_3;
				cloud.at<float>(h, 3) = col_4;
			}
		}
		break;
		case 2:
		{
			for (size_t h = 0; h < cloud_size; h++)
			{
#ifdef _WINDOWS
				if (fscanf_s(file, "%f %f %f %f\n", &col_1, &col_2, &col_3, &col_4) != 4)
#else
				if (fscanf(file, "%f %f %f %f\n", &col_1, &col_2, &col_3, &col_4) != 4)
#endif
				{
					fclose(file);
					return false;
				}

				/*int index = h * channel;
				cloud->data[index] = col_1;
				cloud->data[index + 1] = col_2;
				cloud->data[index + 2] = col_3;
				cloud->data[index + 3] = col_4;*/

				xyz.at<float>(0, h) = col_1;
				xyz.at<float>(1, h) = col_2;
				//xyz.at<float>(2, h) = (col_3 == col_3) ? col_3 : 0;
				xyz.at<float>(2, h) = col_3;
				xyz.at<float>(3, h) = 1;


				int r, c;
				c = h % (int)cloud_width;
				r = h / (int)cloud_width;
				cloud.at<float>(r, c) = col_3 / cloud_dx;

				gray.at<unsigned char>(r, c) = static_cast<unsigned char>(col_4);
			}
		}
		break;
		case 3:
		default:
			return false;
		}
	}
	fclose(file);
	auto endTime = std::chrono::system_clock::now();
	auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime3).count();
	std::cout << duration2 << "\n";

	cv::normalize(cloud, cloud, 0, 65535, cv::NormTypes::NORM_MINMAX);
	cloud.convertTo(cloud, CV_16UC1);

	return true;
}
//txt
void ReadCloud(const char* filename, cv::Mat& xyz)
{
	QFile inFile(filename);
	long size = 0;
	if (inFile.open(QIODevice::ReadOnly))
	{
		{
			QTextStream stream_text(&inFile);
			while (!stream_text.atEnd())
			{
				stream_text.readLine();
				size++;
			}
		}
		inFile.close();
	}
	inFile.open(QIODevice::ReadOnly);
	xyz = cv::Mat(4, size, CV_32FC1);
	QTextStream stream_text(&inFile);
	int i = 0;
	while (!stream_text.atEnd())
	{
		auto line = stream_text.readLine().split(" ");
		xyz.at<float>(0, i) = line.at(0).toFloat();
		xyz.at<float>(1, i) = line.at(1).toFloat();
		xyz.at<float>(2, i) = line.at(2).toFloat();
		xyz.at<float>(3, i) = 1;
		i++;
	}
	inFile.close();
}

void ReadCloud2(const char* filename, cv::Mat& cloud)
{
	std::vector<MyStruct> vec(40000000);
	auto startTime = std::chrono::system_clock::now();
	std::ifstream inFile(filename);
	if (inFile.is_open())
	{
		std::stringstream sstr;
		sstr << inFile.rdbuf();
		std::string str(sstr.str());
		auto startTime4 = std::chrono::system_clock::now();
		auto duration0 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime4 - startTime).count();
		std::cout << duration0 << "\n";
		int index = str.find("\n", 0);
		int lastindex = 0;
		int i = 0;
#if 1
		QStringList linelist;
		while (index != -1)
		{
			linelist << QString::fromStdString(str.substr(lastindex, index - lastindex));
			lastindex = index;
			index = str.find("\n", index + 1);
		}
		auto startTime3 = std::chrono::system_clock::now();
		auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime3 - startTime).count();
		std::cout << duration1 << "\n";
		int size = linelist.size();

		auto read_func = [&](int start, int end) {
			for (int i = start; i < end; i++) {
				auto line = linelist.at(i).split(" ");
				//if (line.size() != 3)continue;
# if 1
				cloud.at<float>(0, i) = line.at(0).toFloat();
				cloud.at<float>(1, i) = line.at(1).toFloat();
				cloud.at<float>(2, i) = line.at(2).toFloat();
# else
				MyStruct m;
				m.x = line.at(0).toFloat();
				m.y = line.at(1).toFloat();
				m.z = line.at(2).toFloat();
				vec[i] = m;
# endif
			}
			};
		std::future<void> ft1 = async(std::launch::async, read_func, 0, size / 4);
		std::future<void> ft2 = async(std::launch::async, read_func, size / 4, size / 2);
		std::future<void> ft3 = async(std::launch::async, read_func, size / 2, size * 3 / 4);
		std::future<void> ft4 = async(std::launch::async, read_func, size * 3 / 4, size);
		ft1.wait();
		ft2.wait();
		ft3.wait();
		ft4.wait();
#else
		while (index != -1)
		{
			QString line = QString::fromStdString(str.substr(lastindex, index - lastindex));

			auto linelist = line.split(" ");
			//if (linelist.size() != 4)continue;
# if 1
			MyStruct pos;
			pos.x = linelist.at(0).toFloat();
			pos.y = linelist.at(1).toFloat();
			pos.z = linelist.at(2).toFloat();
			vec.push_back(pos);
# else
			cloud.at<float>(0, i) = linelist.at(0).toFloat();
			cloud.at<float>(1, i) = linelist.at(1).toFloat();
			cloud.at<float>(2, i) = linelist.at(2).toFloat();
			i++;
# endif
			lastindex = index;
			index = str.find("\n", index + 1);
		}
#endif
		inFile.close();
	}
	auto startTime2 = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - startTime).count();
	std::cout << duration << "\n";
	std::cout << vec.size() << "\n";
}

bool WriteCloud3D(const char* filename, cv::Mat& cloud)
{
	auto startTime = std::chrono::system_clock::now();
	FILE* fp;
	fopen_s(&fp, filename, "a");
	auto startTime2 = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - startTime).count();
	std::cout << "open" << duration << "\n";
	if (NULL == fp)
	{
		return false;
	}

	for (int h = 0; h < cloud.cols; h++)
	{
		float x = cloud.at<float>(0, h);
		float y = cloud.at<float>(1, h);
		float z = cloud.at<float>(2, h);
		if (isnan(x) || isnan(y) || isnan(z))
		{
			continue;
		}
		//float gray = cloud.at<float>(3, h);
		//fprintf(fp, "%f %f %f %f\n", x, y, z, gray);
		fprintf(fp, "%f %f %f\n", x, y, z);
	}
	fclose(fp);
	auto startTime3 = std::chrono::system_clock::now();
	auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime3 - startTime).count();
	std::cout << "write" << duration1 << "\n";
	return true;
}

bool WriteCloud3D2(const char* filename, cv::Mat& cloud)
{
	auto startTime = std::chrono::system_clock::now();
	QFile inFile(filename);
	if (!inFile.open(QIODevice::WriteOnly | QIODevice::Append))return false;
	QByteArray data;
	for (int h = 0; h < cloud.cols; h++)
	{
		data += QString::number(cloud.at<float>(0, h)) + " ";
		data += QString::number(cloud.at<float>(1, h)) + " ";
		data += QString::number(cloud.at<float>(2, h)) + "\n";
	}
	auto startTime2 = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - startTime).count();
	std::cout << "open" << duration << "\n";
	inFile.write(data);
	inFile.close();
	auto startTime3 = std::chrono::system_clock::now();
	auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime3 - startTime).count();
	std::cout << "write" << duration1 << "\n";
	return true;
}

void readwrite(const char* in, const char* out, const char* re)
{
	auto startTime = std::chrono::system_clock::now();
	std::ifstream inFile(in, std::ios::in);
	std::string str;
	if (inFile.is_open())
	{
		std::stringstream sstr;
		sstr << inFile.rdbuf();
		str = sstr.str();
	}
	inFile.close();
	auto startTime3 = std::chrono::system_clock::now();
	auto duration1 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime3 - startTime).count();
	std::cout << "read:" << duration1 << "\n";

	std::ofstream outFile(out, std::ios::out | std::ios::app);
	outFile << str;
	outFile.close();
	auto startTime4 = std::chrono::system_clock::now();
	auto duration2 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime4 - startTime).count();
	std::cout << "write:" << duration2 << "\n";

	std::rename(out, re);

	auto startTime5 = std::chrono::system_clock::now();
	auto duration3 = std::chrono::duration_cast<std::chrono::milliseconds>(startTime5 - startTime).count();
	std::cout << "rename:" << duration3 << "\n";
}

static void callbackFunc(cv::Mat pImg, cv::Mat p3dImg, int nWidth, int mHeight, int nDepth, int nChannels, int cameraIndex, QString strAlgoMask)
{
	auto startTime2 = std::chrono::system_clock::now();
	auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - start_time_point).count();
	std::cout << "callback:" << duration << "\n";
	ImageData_t data;
	data.Data = pImg;
	data.brightImageData = p3dImg;
	data.depth = nDepth;
	data.strAlgoMark = strAlgoMask;
	vecImg << data;
	std::cout << "img mark:" << strAlgoMask.toStdString()
		<< "\ngray imag size:" << pImg.size() << "\n"
		<< "3d img size:" << p3dImg.size() << std::endl;
}

int main(int argc, char* argv[])
{
	QApplication a(argc, argv);

#pragma region 显示测试
#if 0
	QtWidgetsClass w;
	w.show();
#endif // 1
#pragma endregion

#pragma region 翻译测试
# if 0
	QTranslator trans;
	trans.load(qApp->applicationDirPath() + "\\translation\\Translation_zh.qm");
	QCoreApplication::installTranslator(&trans);
	std::cout << "************************************tanslate test************************************" << std::endl;
	MessageBox(NULL, QObject::tr("text").toStdWString().c_str(), QObject::tr("title").toStdWString().c_str(), 0);
# endif
#pragma endregion
#pragma region 相机测试
# if 0
	std::cout << "************************************cam test************************************" << std::endl;
#  ifdef _DEBUG
	std::wstring camlibpath{ qApp->applicationDirPath().toStdWString() + L"\\plugins\\camera_d\\RindoCamera_d.dll" };
	auto libcamera = LoadLibrary(camlibpath.c_str());
#  else
	std::wstring camlibpath{ qApp->applicationDirPath().toStdWString() + L"\\plugins\\camera\\RindoCamera.dll" };
	auto libcamera = LoadLibrary(camlibpath.c_str());
	//auto pcam = new RindoCamera();
#  endif // _DEBUG	
	if (libcamera)
	{
		auto create = (CreatePlugin)GetProcAddress(libcamera, "createPlugin");
		auto pPlugin = static_cast<CameraPlugin*>(create(Q_NULLPTR));
		Camera::CameraConfigStruct cfg;
		cfg.IP = "172.16.1.10";//相机默认ip172.16.1.10
		cfg.cameraIndex = 0;
		cfg.configFile = qApp->applicationDirPath() + "\\conf\\patternconfig.bopixel";
		//Camera::CameraConfigStruct cfg2;
		//cfg2.IP = "192.168.1.10";//相机默认ip172.16.1.10
		//cfg2.cameraIndex = 0;
		//cfg2.configFile = qApp->applicationDirPath() + "\\conf\\patternconfig.bopixel";
		QVector<Camera::CameraType> typeVec;
		pPlugin->supportedCameraTypes(typeVec);
		pPlugin->checkCamera(cfg);
		//pPlugin->checkCamera(cfg2);
		pPlugin->setCallbackFunction(cfg.IP, &callbackFunc, 0);
		std::cout << "connecting..." << std::endl;
		pPlugin->openCamera(cfg.IP);
		std::cout << "connected!wait 1s..." << std::endl;
		std::this_thread::sleep_for(1s);//立刻拍会没图
		QTimer timer;
		bool ret = QObject::connect(&timer, &QTimer::timeout, [=] {
			std::cout << pPlugin->isConnected(cfg.IP);

			});
		timer.start(100);
		while (true)
		{
			std::cout << "\nenter mark string to trigger the camera(enter q to exit)" << std::endl;
			std::string str{};
			std::cin >> str;
			if (!str.compare("q")) break;
			start_time_point = std::chrono::system_clock::now();
			std::cout << pPlugin->isConnected(cfg.IP) << std::endl;
			pPlugin->softwareExecute(cfg.IP, str.c_str());
			//pPlugin->softwareExecute(cfg.IP, (str + ".1").c_str());
			auto startTime2 = std::chrono::system_clock::now();
			auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(startTime2 - start_time_point).count();
			std::cout << "soft:" << duration << "\n";
		}

		//pPlugin->softwareExecute(cfg.IP, "1");
		std::cout << "closing camera..." << std::endl;
		pPlugin->closeCamera(cfg.IP);
	}
	else
	{
		std::wcout << camlibpath << L" cam dll load fail\nerror code:" << GetLastError() << std::endl;
	}
	std::cout << "done" << std::endl;
# endif // 0
#pragma endregion
#pragma region 算法测试
# if 1
	std::cout << "************************************alg test************************************" << std::endl;

#  ifdef _DEBUG
	std::wstring alglibpath{ qApp->applicationDirPath().toStdWString() + L"\\plugins\\algorithm_d\\AmPackAlgPlugin_d.dll" };
	auto libalg = LoadLibrary(alglibpath.c_str());
#  else
	
	std::wstring alglibpath{ qApp->applicationDirPath().toStdWString() + L"/plugins/algorithm/AmPackAlgPlugin.dll" };
	auto libalg = LoadLibrary(alglibpath.c_str());
#  endif // _DEBUG
	//AmPackAlgPlugin* test = new AmPackAlgPlugin;
	if (libalg)
	{
		auto create = (CreatePlugin)GetProcAddress(libalg, "createPlugin");
		//auto create2 = (CreatePlugin)GetProcAddress(libalg, "createPlugin");
		auto pPlugin = static_cast<AlgorithmPlugin*>(create(Q_NULLPTR));
		//auto pPlugin2 = static_cast<AlgorithmPlugin*>(create(Q_NULLPTR));
		pPlugin->algoOperate(emAlgoOperate::ALGO_OPERATE_INIT);
		auto list = pPlugin->getAlgoMarkList();
		qDebug() << list;

		//std::cout << "poly init" << FindProcessIDByName("polyworks.exe") && FindProcessIDByName("iminspect.exe");

		QList<algoItemStruct> alglist;
		QVector<DetectResult_t> resVec;
#   pragma region 点云测试
#    if 1
		//cu
		cv::Mat cu_depth, cu_xyz, cu_gray;
		QVector<ImageData_t> cudingwei;
		//ReadCloud3D("D:\\ampackData\\11.pcp", cu_depth, cu_xyz, cu_gray);
		ImageData_t cu;
		cu.strAlgoMark = "9998";
		cu.Data = cu_gray;
		cu.brightImageData = cu_xyz;
		cudingwei.push_back(cu);
		//pPlugin->detect(resVec, cudingwei, alglist);
		//auto map = resVec.last().mapInfo;

		//jing
		cv::Mat depth, xyz;
		QStringList path{
			"D:\\ampackData\\test\\GaGaGa20240420001\\2004.txt"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2001.txt"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2002.txt"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2003.txt"
			//{ "D:\\ampackData\\test\\\\1.pcp","" }
			//,{"D:\\ampackData\\test\\2.pcp",""}
			//,{"D:\\ampackData\\test\\3.pcp",""}
			//,{"D:\\ampackData\\test\\4.pcp",""}
		};
#if 0
		for (const auto& xyzp : path)
		{
			QVector<ImageData_t> jingdingweiImg;
			cv::Mat depth, xyz, gray;
			//pcp
			//ReadCloud3D(xyzp.toStdString().c_str(), depth, xyz, gray);
			//txt+tif
			ReadCloud(xyzp.toStdString().c_str(), xyz);
			//depth = cv::imread(depp.toStdString().c_str(), cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);

			int index1 = xyzp.lastIndexOf("\\") + 1;
			int index2 = xyzp.lastIndexOf(".");
			QString mark = xyzp.mid(index1, index2 - index1);
			ImageData_t data;
			data.Data = depth;
			data.brightImageData = xyz;
			data.strAlgoMark = mark;
			//data.mapInfo = map;
			jingdingweiImg.push_back(data);
			pPlugin->detect(resVec, jingdingweiImg, alglist);
		}
#endif // 0

		QStringList tiffpath{
			"D:\\ampackData\\test\\GaGaGa20240420001\\2004.tif"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2001.tif"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2002.tif"
			,"D:\\ampackData\\test\\GaGaGa20240420001\\2003.tif"
		};

		//QDir dir("D:\\ampackData\\A-111111111371111");
		//QDir dir("C:\\Users\\442\\Desktop\\123");

		//QVector<QString> vstrSubfolders = { "T41219143426-PACK055-1","T41219144309-PACK055","T41219145445-PACK055","T41219150232-PACK055","T41219151030-PACK055","T41219151835-PACK055","T41219162145-PACK117-1","T41219163211-PACK117","T41219164024-PACK117","T41219164835-PACK117","T41219165651-PACK117","T41219170445-PACK117","T41219171624-PACK137-1","T41219172421-PACK137","T41219173221-PACK137","T41219174015-PACK137","T41219174814-PACK137","T41219175608-PACK137","T41219183804-PACK138-1","T41219184607-PACK138","T41219185805-PACK138","T41219190647-PACK138","T41219191502-PACK138","T41219192314-PACK138"};

		QVector<QString> vstrSubfolders = { "T41219093648_PACK100_1", "T41219094411_PACK100", "T41219095052_PACK100", \
			"T41219095735_PACK100", "T41219100436_PACK100", "T41219101137_PACK100", "T41219101845", "T41219102523"	};
 

		//QString Folder = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\A\\PACK100\\SendXYZABC_A\\";
		QString Folder = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\B\\PACK100\\SendXYZABC_B\\";
		QString ABPath;
		bool bIsB =       1      ;
		//ABPath = "F:\\bluelight\\cloudpoint\\0156_1220ScanBiaoDing\\0156BlueLightCloud\\T41220135523-A\\";  

		ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\A\\PACK100\\SendXYZABC_A\\T41219093648_PACK100_1\\";
		//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\A\\SendXYZABC\\T41219143426-PACK055-1\\";
		//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\Pack100\\T41219093648-A\\";
		//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\A\\T41219143426-PACK055-1\\_new\\";
		//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\T41219143426-055-A";
		if (bIsB)
		{
			//ABPath = "F:\\bluelight\\cloudpoint\\0156_1220ScanBiaoDing\\0156BlueLightCloud\\T41220135523-B\\";

			ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\B\\PACK100\\SendXYZABC_B\\T41219093648_PACK100_single1\\";
			//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\T41219143426-055-B";
			//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\B\\SendXYZABC\\T41219143426-PACK055-1\\";
			//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\B\\T41219143426-PACK055-1\\_new\\";
			//ABPath = "F:\\bluelight\\cloudpoint\\1219duibiaoPack\\Pack100\\T41219093648-B\\";
		}
		QDir dir(ABPath);
		auto infolist = dir.entryInfoList(QStringList() << "*.txt", QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort);
		
		//w.AddPLYData("D:\\ampackData\\222.ply");
		//一般点位
		int j = 11;
		int k = 0;
		//for (const auto& xyzp : path)
		int nName = 0 ;
		QString strCloudName = "Pack100-croptest-0108-";
		for(int cloudind = 0; cloudind< 1 ; cloudind++) // vstrSubfolders.size()
		{  
			//strCloudName = vstrSubfolders[cloudind];
			//ABPath = Folder + strCloudName;
			//
			//QDir dir(ABPath);
			//auto infolist = dir.entryInfoList(QStringList() << "*.txt", QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort);

			QString info = QString("*************   cloudind:")+ (bIsB?"-B-":"-A-") + QString::number(cloudind) + QString("  ***********");
			std::cout << info.toStdString() << std::endl;
			for (const auto& xyzp : infolist)
			{
				QVector<ImageData_t> dianweiImg;
				cv::Mat depth, xyz, gray;
				int ss = time(0);
				//pcp
				//ReadCloud3D(xyzp.toStdString().c_str(), depth, xyz, gray);
				//txt+tif
				ReadCloud(xyzp.absoluteFilePath().toStdString().c_str(), xyz);
				//ReadCloud(xyzp.toStdString().c_str(), xyz);
				auto& depthpath = xyzp.absoluteFilePath().replace("txt", "tif");
				//depth = cv::imread(depthpath.toStdString().c_str(), cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
				//gray = cv::Mat::zeros(depth.rows, depth.cols, CV_8UC1);
				ImageData_t data;
				data.Data = depth;
				data.brightImageData = xyz;

				//data.strAlgoMark = QString::number(j);
				data.strAlgoMark = xyzp.baseName();
				data.test_mode = Plugin::TestMode(6);
				if (QRegExp("([A-a,0-9]+)_([A-a,0-9]+)_([A-a,0-9]+)").exactMatch(xyzp.baseName()))continue;
				dianweiImg.push_back(data);
				pPlugin->detect(resVec, dianweiImg, alglist);
				auto mat = resVec.last().mapInfo.value(dianweiImg.at(0).strAlgoMark).value<cv::Mat>();
				//WriteCloud3D(("D:\\ampackData\\test\\" + tmp.at(0).strAlgoMark + ".txt").toStdString().c_str(), mat);

				QString filepath;
				filepath = QString("D:\\ampackData\\") + strCloudName + QString::number(nName + cloudind) + (bIsB ? "-B" : "-A") + QString(".txt");
				//filepath = Folder + strCloudName + (bIsB ? "-B" : "-A") +  QString(".txt");
				WriteCloud3D(filepath.toStdString().c_str(), mat);


				//if (mat.rows > 3)
				//{
				//	//test write point range
				//	double minValue, maxValue;    // 最大值，最小值
				//	cv::Point  minIdx, maxIdx;    // 最小值坐标，最大值坐标   
				//	cv::minMaxLoc(mat.row(0), &minValue, &maxValue, &minIdx, &maxIdx);
				//	QString resMaxMinVal = QString("") + QString::number(minValue) + "," + QString::number(maxValue) + ",";
				//	cv::minMaxLoc(mat.row(1), &minValue, &maxValue, &minIdx, &maxIdx);
				//	resMaxMinVal = resMaxMinVal + QString::number(minValue) + "," + QString::number(maxValue) + ",";
				//	cv::minMaxLoc(mat.row(2), &minValue, &maxValue, &minIdx, &maxIdx);
				//	resMaxMinVal = resMaxMinVal + QString::number(minValue) + "," + QString::number(maxValue);
				//	QFile file(g_pSetting->getFormulaPath() + "/fovrange/A/" + data.strAlgoMark + "_fovrange.txt");
				//	if (file.open(QIODevice::WriteOnly | QIODevice::Text))
				//	{
				//		file.write(resMaxMinVal.toStdString().c_str());
				//		file.close();
				//	}
				//}

				//w.AddPointCloud(mat, k+1);
				j += 10;
				k++;
			}
			
		}
#    endif // 0	
#   pragma endregion
#   pragma region Poly测试
#	 if 0
		//总，调用ploywork
		QVector<ImageData_t> all;
		ImageData_t a;
		a.strAlgoMark = "9999";
		a.imagePath = "D:\\Git\\am-pack\\cloud_test_full;";

		//QMap<QString, QVariant> map{ {"path_A",""},{path_} };
		//a.mapInfo = map;
		//cv::Mat test_mat;
		//ReadCloud("D:\\IMAGE\\LGQCC_eur2.txt", test_mat);
		//a.Data = test_mat;
		a.strQrCode = "QR123";
		a.test_mode = Plugin::TestMode(6);
		all.push_back(a);
		pPlugin->detect(resVec, all, alglist);
#	 endif // 0
#   pragma endregion	
		//pPlugin->algoOperate(emAlgoOperate::ALGO_OPERATE_PARAM_CHANGE);
	}
	else
	{
		std::wcout << alglibpath << L" cam dll load fail\nerror code:" << GetLastError() << std::endl;
	}
# endif // 0
#pragma endregion

#pragma region 读写测试
#if 0
	std::cout << "************************************read test************************************" << std::endl;
	cv::Mat img;
	cv::Mat img2(4, 40000000, CV_32FC1);

	ReadCloud("D:\\ampackData\\test\\all.txt", img);
	//ReadCloud2("D:\\ampackData\\leftnew - Cloud.txt", img2);
	//WriteCloud3D("D:\\ampackData\\rightnew2test.txt", img2);
	//readwrite("D:\\ampackData\\leftnew - Cloud.txt", "D:\\ampackData\\rightnew2test.txt", "D:\\ampackData\\rightnew2test2.txt");
#endif // 0
#pragma endregion
	//auto release = (ReleasePlugin)GetProcAddress(libcamera, "releasePlugin");
	//release = (ReleasePlugin)GetProcAddress(libalg, "releasePlugin");
	std::cout << "************************************end test************************************" << std::endl;
	return a.exec();
}
